// 腾讯云ASR WebSocket服务类
class TencentASRWebSocket {
    constructor(config) {
        this.config = config;
        this.websocket = null;
        this.isConnected = false;
        this.voiceId = '';
        this.audioContext = null;
        this.processor = null;
        this.audioBuffer = [];
        this.isRecording = false;
        
        // 事件回调
        this.onRecognitionResult = null;
        this.onSentenceEnd = null;
        this.onRecognitionComplete = null;
        this.onError = null;
        this.onConnected = null;
        this.onAudioData = null; // 音频数据回调
    }

    // 生成VoiceId
    generateVoiceId() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            const r = Math.random() * 16 | 0;
            const v = c === 'x' ? r : (r & 0x3 | 0x8);
            return v.toString(16);
        });
    }

    // 生成随机数
    generateNonce() {
        return Math.floor(Date.now() / 1000).toString();
    }

    // 生成时间戳
    generateTimestamp() {
        return Math.floor(Date.now() / 1000).toString();
    }

    // 生成过期时间
    generateExpired() {
        return (Math.floor(Date.now() / 1000) + 3600).toString(); // 1小时后过期
    }

    // HMAC-SHA1签名算法
    async hmacSHA1(key, data) {
        const encoder = new TextEncoder();
        const keyData = encoder.encode(key);
        const dataToSign = encoder.encode(data);
        
        const cryptoKey = await crypto.subtle.importKey(
            'raw',
            keyData,
            { name: 'HMAC', hash: 'SHA-1' },
            false,
            ['sign']
        );
        
        const signature = await crypto.subtle.sign('HMAC', cryptoKey, dataToSign);
        const signatureArray = new Uint8Array(signature);
        return btoa(String.fromCharCode(...signatureArray));
    }

    // 构建WebSocket URL
    async buildWebSocketURL() {
        const nonce = this.generateNonce();
        const timestamp = this.generateTimestamp();
        const expired = this.generateExpired();
        this.voiceId = this.generateVoiceId();

        // 构建查询参数（不包含signature）
        const queryParams = {
            'engine_model_type': this.config.engineModelType,
            'expired': expired,
            'filter_dirty': this.config.filterDirty.toString(),
            'filter_modal': this.config.filterModal.toString(),
            'filter_punc': this.config.filterPunc.toString(),
            'needvad': this.config.needVad.toString(),
            'nonce': nonce,
            'secretid': this.config.secretId,
            'timestamp': timestamp,
            'voice_format': this.config.voiceFormat.toString(),
            'voice_id': this.voiceId,
            'vad_silence_time': this.config.vadSilenceTime.toString()
        };

        // 按字典序排序参数
        const sortedParams = Object.keys(queryParams)
            .sort()
            .map(key => `${key}=${queryParams[key]}`)
            .join('&');

        // 构造签名原文
        const signatureString = `asr.cloud.tencent.com/asr/v2/${this.config.appId}?${sortedParams}`;
        console.log('签名原文:', signatureString);

        // 使用HMAC-SHA1加密
        const signature = await this.hmacSHA1(this.config.secretKey, signatureString);
        console.log('生成的签名:', signature);

        // URL编码签名
        const encodedSignature = encodeURIComponent(signature);
        console.log('URL编码后的签名:', encodedSignature);

        // 构建完整URL
        const url = `wss://${this.config.endpoint}/asr/v2/${this.config.appId}?${sortedParams}&signature=${encodedSignature}`;
        console.log('WebSocket URL:', url);

        return url;
    }

    // 连接WebSocket
    async connect() {
        try {
            const url = await this.buildWebSocketURL();
            this.websocket = new WebSocket(url);

            this.websocket.onopen = () => {
                console.log('WebSocket连接已建立');
                this.isConnected = true;
                if (this.onConnected) {
                    this.onConnected(this.voiceId);
                }
            };

            this.websocket.onmessage = (event) => {
                this.handleMessage(event.data);
            };

            this.websocket.onclose = (event) => {
                console.log('WebSocket连接已关闭:', event.code, event.reason);
                this.isConnected = false;
            };

            this.websocket.onerror = (error) => {
                console.error('WebSocket错误:', error);
                if (this.onError) {
                    this.onError(error);
                }
            };

        } catch (error) {
            console.error('连接WebSocket失败:', error);
            if (this.onError) {
                this.onError(error);
            }
        }
    }

    // 处理接收到的消息
    handleMessage(data) {
        try {
            const response = JSON.parse(data);
            console.log('收到ASR响应:', response);

            if (response.code !== 0) {
                const error = new Error(`ASR错误: ${response.message}`);
                if (this.onError) {
                    this.onError(error);
                }
                return;
            }

            // 握手成功
            if (!this.isConnected && response.voice_id) {
                this.isConnected = true;
                if (this.onConnected) {
                    this.onConnected(response.voice_id);
                }
                return;
            }

            // 识别完成
            if (response.final === 1) {
                if (this.onRecognitionComplete) {
                    this.onRecognitionComplete(response.voice_id);
                }
                return;
            }

            // 识别结果
            if (response.result) {
                const result = response.result;
                console.log('识别结果详情:', result);
                
                if (result.slice_type === 2) { // 句子结束
                    console.log('句子结束:', result.voice_text_str);
                    if (this.onSentenceEnd) {
                        result.audioId = 'msg_' + Date.now(); // 添加唯一音频ID
                        this.onSentenceEnd(result);
                    }
                } else {
                    console.log('实时结果:', result.voice_text_str);
                    if (this.onRecognitionResult) {
                        this.onRecognitionResult(result);
                    }
                }
            }

        } catch (error) {
            console.error('解析ASR响应失败:', error);
            if (this.onError) {
                this.onError(error);
            }
        }
    }

    // 发送音频数据
    sendAudioData(audioData) {
        if (!this.isConnected || !this.websocket) {
            console.warn('WebSocket未连接，无法发送音频数据');
            return;
        }

        try {
            this.websocket.send(audioData);
            
            // 触发音频数据回调用于说话人识别
            var audioJson = {
                data: audioData,
                id: "msg_" + Date.now(),
            }
            if (this.onAudioData) {
                this.onAudioData(audioJson);
            }
        } catch (error) {
            console.error('发送音频数据失败:', error);
            if (this.onError) {
                this.onError(error);
            }
        }
    }

    // 发送结束消息
    sendEndMessage() {
        if (!this.isConnected || !this.websocket) {
            return;
        }

        const endMessage = { type: 'end' };
        try {
            this.websocket.send(JSON.stringify(endMessage));
        } catch (error) {
            console.error('发送结束消息失败:', error);
        }
    }

    // 断开连接
    disconnect() {
        if (this.websocket) {
            this.sendEndMessage();
            this.websocket.close();
            this.websocket = null;
        }
        this.isConnected = false;
    }

    // 设置音频处理
    async setupAudioProcessing(stream) {
        try {
            // 使用配置中的音频设置，如果没有则使用默认值
            const audioConfig = this.config.audioConfig || {
                sampleRate: 44100,
                channelCount: 1,
                echoCancellation: true,
                noiseSuppression: true,
                autoGainControl: true,
                latency: 0.01
            };

            this.audioContext = new (window.AudioContext || window.webkitAudioContext)({
                sampleRate: audioConfig.sampleRate
            });

            const source = this.audioContext.createMediaStreamSource(stream);
            
            // 使用更现代的AudioWorklet替代ScriptProcessor（如果支持）
            if (this.audioContext.audioWorklet) {
                await this.setupAudioWorklet(source, audioConfig);
            } else {
                // 降级到ScriptProcessor
                this.setupScriptProcessor(source, audioConfig);
            }

        } catch (error) {
            console.error('设置音频处理失败:', error);
            if (this.onError) {
                this.onError(error);
            }
        }
    }

    // 设置AudioWorklet（现代方式）
    async setupAudioWorklet(source, audioConfig) {
        try {
            // 创建AudioWorklet处理器
            const workletCode = `
                class AudioProcessor extends AudioWorkletProcessor {
                    constructor() {
                        super();
                        this.bufferSize = 4096;
                        this.buffer = new Float32Array(this.bufferSize);
                        this.bufferIndex = 0;
                    }
                    
                    process(inputs, outputs, parameters) {
                        const input = inputs[0];
                        if (input.length > 0) {
                            const inputData = input[0];
                            
                            for (let i = 0; i < inputData.length; i++) {
                                this.buffer[this.bufferIndex++] = inputData[i];
                                
                                if (this.bufferIndex >= this.bufferSize) {
                                    this.port.postMessage({
                                        type: 'audioData',
                                        data: new Float32Array(this.buffer)
                                    });
                                    this.bufferIndex = 0;
                                }
                            }
                        }
                        return true;
                    }
                }
                registerProcessor('audio-processor', AudioProcessor);
            `;

            const blob = new Blob([workletCode], { type: 'application/javascript' });
            const workletURL = URL.createObjectURL(blob);
            
            await this.audioContext.audioWorklet.addModule(workletURL);
            
            this.workletNode = new AudioWorkletNode(this.audioContext, 'audio-processor');
            this.workletNode.port.onmessage = (event) => {
                if (event.data.type === 'audioData' && this.isRecording) {
                    // 重采样到16kHz（腾讯ASR要求）
                    const resampledData = this.resampleAudio(event.data.data, audioConfig.sampleRate, 16000);
                    const pcmData = this.convertTo16BitPCM(resampledData);
                    this.sendAudioData(pcmData);
                }
            };

            source.connect(this.workletNode);
            this.workletNode.connect(this.audioContext.destination);
            
            URL.revokeObjectURL(workletURL);
            console.log('使用AudioWorklet进行音频处理');

        } catch (error) {
            console.warn('AudioWorklet不支持，降级到ScriptProcessor:', error);
            this.setupScriptProcessor(source, audioConfig);
        }
    }

    // 设置ScriptProcessor（兼容方式）
    setupScriptProcessor(source, audioConfig) {
        this.processor = this.audioContext.createScriptProcessor(4096, 1, 1);

        this.processor.onaudioprocess = (event) => {
            if (!this.isRecording) return;

            const inputBuffer = event.inputBuffer;
            const inputData = inputBuffer.getChannelData(0);
            
            // 重采样到16kHz（腾讯ASR要求）
            const resampledData = this.resampleAudio(inputData, audioConfig.sampleRate, 16000);
            
            // 转换为16位PCM
            const pcmData = this.convertTo16BitPCM(resampledData);
            
            // 发送音频数据
            this.sendAudioData(pcmData);
        };

        source.connect(this.processor);
        this.processor.connect(this.audioContext.destination);
        console.log('使用ScriptProcessor进行音频处理');
    }

    // 音频重采样（简单线性插值）
    resampleAudio(inputData, inputSampleRate, outputSampleRate) {
        if (inputSampleRate === outputSampleRate) {
            return inputData;
        }
        
        const ratio = inputSampleRate / outputSampleRate;
        const outputLength = Math.floor(inputData.length / ratio);
        const outputData = new Float32Array(outputLength);
        
        for (let i = 0; i < outputLength; i++) {
            const inputIndex = i * ratio;
            const index = Math.floor(inputIndex);
            const fraction = inputIndex - index;
            
            if (index + 1 < inputData.length) {
                // 线性插值
                outputData[i] = inputData[index] * (1 - fraction) + inputData[index + 1] * fraction;
            } else {
                outputData[i] = inputData[index];
            }
        }
        
        return outputData;
    }

    // 转换为16位PCM格式
    convertTo16BitPCM(float32Array) {
        const buffer = new ArrayBuffer(float32Array.length * 2);
        const view = new DataView(buffer);
        let offset = 0;
        
        for (let i = 0; i < float32Array.length; i++, offset += 2) {
            let s = Math.max(-1, Math.min(1, float32Array[i]));
            view.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
        }
        
        return buffer;
    }

    // 开始录音
    async startRecording() {
        try {
            // 先建立WebSocket连接
            await this.connect();
            
            // 等待连接建立
            await new Promise((resolve, reject) => {
                const checkConnection = () => {
                    if (this.isConnected) {
                        resolve();
                    } else {
                        setTimeout(checkConnection, 100);
                    }
                };
                setTimeout(() => {
                    if (!this.isConnected) {
                        reject(new Error('WebSocket连接超时'));
                    }
                }, 5000);
                checkConnection();
            });

            // 使用配置中的音频设置
            const audioConfig = this.config.audioConfig || {
                sampleRate: 44100,
                channelCount: 1,
                echoCancellation: true,
                noiseSuppression: true,
                autoGainControl: true,
                latency: 0.01
            };

            const stream = await navigator.mediaDevices.getUserMedia({
                audio: {
                    sampleRate: audioConfig.sampleRate,
                    channelCount: audioConfig.channelCount,
                    echoCancellation: audioConfig.echoCancellation,
                    noiseSuppression: audioConfig.noiseSuppression,
                    autoGainControl: audioConfig.autoGainControl,
                    latency: audioConfig.latency
                }
            });

            await this.setupAudioProcessing(stream);
            
            this.isRecording = true;
            console.log('开始录音');

        } catch (error) {
            console.error('开始录音失败:', error);
            if (this.onError) {
                this.onError(error);
            }
        }
    }

    // 停止录音
    stopRecording() {
        this.isRecording = false;
        
        if (this.processor) {
            this.processor.disconnect();
            this.processor = null;
        }
        
        if (this.workletNode) {
            this.workletNode.disconnect();
            this.workletNode = null;
        }
        
        if (this.audioContext) {
            this.audioContext.close();
            this.audioContext = null;
        }
        
        this.sendEndMessage();
        console.log('停止录音');
    }

    // 清理资源
    cleanup() {
        this.stopRecording();
        this.disconnect();
    }
}

// 导出类
if (typeof module !== 'undefined' && module.exports) {
    module.exports = TencentASRWebSocket;
} else {
    window.TencentASRWebSocket = TencentASRWebSocket;
}
